package com.fast.develop.dm.integration.web;

import cn.hutool.core.util.StrUtil;
import com.fast.develop.dm.core.properties.DomainRuntimeProperties;
import com.fast.develop.dm.core.vo.PageReq;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * @author 莫寅
 * @createTime 2022-06-05 23:21
 * @desc：
 */
@Slf4j
public class DomainRequestMappingHandlerMapping {

    private DomainRuntimeProperties domainRuntimeProperties;
    private RequestMappingHandlerMapping requestMappingHandlerMapping;
    private DomainModelResourcesRest domainModelResourcesRest;

    public DomainRequestMappingHandlerMapping(DomainRuntimeProperties domainRuntimeProperties, RequestMappingHandlerMapping requestMappingHandlerMapping, DomainModelResourcesRest domainModelResourcesRest) {
        this.domainRuntimeProperties = domainRuntimeProperties;
        this.requestMappingHandlerMapping = requestMappingHandlerMapping;
        this.domainModelResourcesRest = domainModelResourcesRest;
    }

    @SneakyThrows
    public void registerResourcesMapping() {
        String apiPrefix = StrUtil.isNotBlank(domainRuntimeProperties.getPrefix()) ? domainRuntimeProperties.getPrefix() : "";

        // 注册资源查询
        RequestMappingInfo resourcesInfo = RequestMappingInfo.paths(apiPrefix + "/{model}").methods(RequestMethod.GET).build();
        registerMapping(resourcesInfo, DomainModelResourcesRest.class.getDeclaredMethod("resources", String.class, PageReq.class));

        // 注册创建资源
        RequestMappingInfo createInfo = RequestMappingInfo.paths(apiPrefix + "/{model}").methods(RequestMethod.POST).build();
        registerMapping(createInfo, DomainModelResourcesRest.class.getDeclaredMethod("create", String.class, Map.class));

        // 注册修改资源
        RequestMappingInfo updateInfo = RequestMappingInfo.paths(apiPrefix + "/{model}/{id}").methods(RequestMethod.PUT).build();
        registerMapping(updateInfo, DomainModelResourcesRest.class.getDeclaredMethod("update", String.class, String.class, Map.class));

        // 注册删除资源
        RequestMappingInfo deleteInfo = RequestMappingInfo.paths(apiPrefix + "/{model}/{id}").methods(RequestMethod.DELETE).build();
        registerMapping(deleteInfo, DomainModelResourcesRest.class.getDeclaredMethod("delete", String.class, String.class));

        // 注册获取资源
        RequestMappingInfo getInfo = RequestMappingInfo.paths(apiPrefix + "/{model}/{id}").methods(RequestMethod.GET).build();
        registerMapping(getInfo, DomainModelResourcesRest.class.getDeclaredMethod("get", String.class, String.class));
    }


    public void unRegisterResourcesMapping(){
        String apiPrefix = StrUtil.isNotBlank(domainRuntimeProperties.getPrefix()) ? domainRuntimeProperties.getPrefix() : "";

        // 注册资源查询
        RequestMappingInfo resourcesInfo = RequestMappingInfo.paths(apiPrefix + "/{model}").methods(RequestMethod.GET).build();
        unRegisterMapping(resourcesInfo);

        // 注册创建资源
        RequestMappingInfo createInfo = RequestMappingInfo.paths(apiPrefix + "/{model}").methods(RequestMethod.POST).build();
        unRegisterMapping(createInfo);

        // 注册修改资源
        RequestMappingInfo updateInfo = RequestMappingInfo.paths(apiPrefix + "/{model}/{id}").methods(RequestMethod.PUT).build();
        unRegisterMapping(updateInfo);

        // 注册删除资源
        RequestMappingInfo deleteInfo = RequestMappingInfo.paths(apiPrefix + "/{model}/{id}").methods(RequestMethod.DELETE).build();
        unRegisterMapping(deleteInfo);

        // 注册获取资源
        RequestMappingInfo getInfo = RequestMappingInfo.paths(apiPrefix + "/{model}/{id}").methods(RequestMethod.GET).build();
        unRegisterMapping(getInfo);
    }

    private void registerMapping(RequestMappingInfo resourcesInfo, Method method){
        try{
            requestMappingHandlerMapping.registerMapping(resourcesInfo, domainModelResourcesRest, method);
        }catch (Exception e){
            log.warn("mapping已存在！不能重复注册：{}", resourcesInfo);
        }
    }

    private void unRegisterMapping(RequestMappingInfo requestMappingInfo){
        try{
            requestMappingHandlerMapping.unregisterMapping(requestMappingInfo);
        }catch (Exception e){
            log.warn("mapping已不存在！{}", requestMappingInfo);
        }
    }
}
